package com.heima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.heima.mapper.NodeMapper;
import com.heima.mapper.RegionMapper;
import com.heima.mapper.VendingMachineMapper;
import com.heima.mapper.VmTypeMapper;
import com.heima.pojo.Node;
import com.heima.pojo.Region;
import com.heima.pojo.VendingMachine;
import com.heima.pojo.VmType;
import com.heima.pojo.dto.NodeDto;
import com.heima.pojo.vo.*;
import com.heima.service.NodeService;
import com.heima.utils.PageResult;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 赵超
 */
@Service
@AllArgsConstructor
public class NodeServiceImpl extends ServiceImpl<NodeMapper, Node> implements NodeService {
    private NodeMapper nodeMapper;
    private VendingMachineMapper vendingMachineMapper;
    private VmTypeMapper vmTypeMapper;
    private RegionMapper regionMapper;

    @Override
    public PageResult<NodeDetailVo> getRegionById(String name, Long regionId, Integer pageIndex, Integer pageSize) {
        Node node = new Node();
        node.setName(name);
        node.setRegionId(regionId);


        PageHelper.startPage(pageIndex, pageSize);
        Page<NodeDetailVo> list = nodeMapper.selectDetailByPlanId(node);
        Integer totalPage = list.getPages();
        Long totalCount = list.getTotal();
        return new PageResult<>(pageIndex, pageSize, totalPage, totalCount, list);
    }

    @Override
    public int add(NodeDto nodeDto) {
        Node node = new Node();
        BeanUtils.copyProperties(nodeDto, node);
        node.setAreaCode(nodeDto.getAreaCode() + "");
        return nodeMapper.insert(node);
    }

    @Override
    public List<NodeMachineDetailVo> getVmList(Integer id) {
        List<NodeMachineDetailVo> list = new ArrayList<>();

        //1 根据id查询VendingMachine集合
        LambdaQueryWrapper<VendingMachine> lqw = new LambdaQueryWrapper<>();
        lqw.eq(VendingMachine::getNodeId, id);
        List<VendingMachine> vendingMachines = vendingMachineMapper.selectList(lqw);

        if (CollectionUtils.isEmpty(vendingMachines)) {
            return list;
        }

        //提取需要的ID 集合，用于批量查询
        Set<Integer> vmTypeIds = new HashSet<>();
        Set<Long> regionIds = new HashSet<>();
        Set<Long> nodeIds = vendingMachines.stream()
                .map(VendingMachine::getNodeId)
                .collect(Collectors.toSet());

        vendingMachines.forEach(vendingMachine -> {
            vmTypeIds.add(vendingMachine.getVmType());
            regionIds.add(vendingMachine.getRegionId());
            nodeIds.add(vendingMachine.getNodeId());
        });

        // 2. 批量查询 VmType
        LambdaQueryWrapper<VmType> vtQuery = new LambdaQueryWrapper<>();
        vtQuery.in(VmType::getTypeId, vmTypeIds);
        List<VmType> vmTypes = vmTypeMapper.selectList(vtQuery);
        Map<Integer, VmTypeVo> vmTypeMap = vmTypes.stream()
                .collect(Collectors.toMap(VmType::getTypeId, vmType -> {
                    VmTypeVo vmTypeVo = new VmTypeVo();
                    BeanUtils.copyProperties(vmType, vmTypeVo);
                    return vmTypeVo;
                }));

        //3.批量查询 Region
        List<Region> regions = regionMapper.selectBatchIds(regionIds);
        Map<Long, RegionVo> regionMap = regions.stream()
                .collect(Collectors.toMap(Region::getId, region -> {
                    RegionVo regionVo = new RegionVo();
                    BeanUtils.copyProperties(region, regionVo);
                    return regionVo;
                }));

        //4.批量查询调用自己写的sql NodeVo
        List<NodeDetailVo> nodeDetailVos = nodeMapper.selectNodeDetailByIds(new ArrayList<>(nodeIds));
        Map<Long, NodeDetailVo> collect = nodeDetailVos
                .stream()
                .collect(Collectors.toMap(NodeDetailVo::getId, Function.identity()));

        //5.组装结果
        vendingMachines.forEach(vm -> {
            NodeMachineDetailVo detailVo = new NodeMachineDetailVo();
            BeanUtils.copyProperties(vm, detailVo);
            //设置VmType
            detailVo.setType(vmTypeMap.get(vm.getVmType()));
            //设置 Region
            detailVo.setRegion(regionMap.get(vm.getRegionId()));
            //设置 Node
            detailVo.setNode(collect.get(vm.getNodeId()));

            list.add(detailVo);
        });


        return list;
    }

    @Override
    public int update(Integer id, NodeDto nodeDto) {
        Node node = new Node();
        BeanUtils.copyProperties(nodeDto, node);
        node.setId(Long.valueOf(id));
        return nodeMapper.updateById(node);
    }

    @Override
    public int delete(Integer id) {
        return nodeMapper.deleteById(id);
    }
}
